// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once // 预编译头指令，确保该头文件只被编译一次

#include "GameplayEffectTypes.h" // 包含GameplayEffect类型定义的头文件

#include "LyraGameplayEffectContext.generated.h" // 包含由Unreal Header Tool生成的代码的头文件

class AActor; // 前向声明AActor类
class FArchive; // 前向声明FArchive类
class ILyraAbilitySourceInterface; // 前向声明ILyraAbilitySourceInterface接口类
class UObject; // 前向声明UObject类
class UPhysicalMaterial; // 前向声明UPhysicalMaterial类

USTRUCT() // USTRUCT宏，声明一个UStruct，可被反射系统识别
struct FLyraGameplayEffectContext : public FGameplayEffectContext // 定义结构体FLyraGameplayEffectContext，公有继承自FGameplayEffectContext
{
	GENERATED_BODY() // GENERATED_BODY宏，必须出现在UStruct的主体开始处，用于生成反射代码

	FLyraGameplayEffectContext() // 默认构造函数
		: FGameplayEffectContext() // 调用父类FGameplayEffectContext的默认构造函数
	{
	}

	FLyraGameplayEffectContext(AActor* InInstigator, AActor* InEffectCauser) // 带参数的构造函数
		: FGameplayEffectContext(InInstigator, InEffectCauser) // 调用父类FGameplayEffectContext的带参构造函数
	{
	}

	/** 
	 * 从FGameplayEffectContextHandle中提取出封装的FLyraGameplayEffectContext指针
	 * @param Handle 游戏效果上下文句柄
	 * @return 成功则返回FLyraGameplayEffectContext指针，失败（不存在或类型错误）则返回nullptr
	 */
	static LYRAGAME_API FLyraGameplayEffectContext* ExtractEffectContext(struct FGameplayEffectContextHandle Handle); // 静态成员函数声明，用于从句柄中提取特定类型的上下文

	/** 
	 * 设置用作能力源的对象
	 * @param InObject 实现了ILyraAbilitySourceInterface接口的对象
	 * @param InSourceLevel 源等级
	 */
	void SetAbilitySource(const ILyraAbilitySourceInterface* InObject, float InSourceLevel); // 成员函数声明，设置能力源对象

	/** 
	 * 获取与源对象关联的能力源接口
	 * @return 返回能力源接口指针，仅在权威端有效
	 */
	const ILyraAbilitySourceInterface* GetAbilitySource() const; // 成员函数声明，获取能力源对象

	/** 
	 * 复制当前上下文对象
	 * @return 返回一个新分配的FLyraGameplayEffectContext对象，是当前对象的深拷贝
	 */
	virtual FGameplayEffectContext* Duplicate() const override // 重写父类的虚函数Duplicate，用于复制上下文
	{
		FLyraGameplayEffectContext* NewContext = new FLyraGameplayEffectContext(); // 在堆上分配一个新的FLyraGameplayEffectContext对象
		*NewContext = *this; // 使用赋值操作符进行浅拷贝
		if (GetHitResult()) // 检查当前上下文是否包含有效的命中结果
		{
			// 对命中结果进行深拷贝，并添加到新上下文中
			NewContext->AddHitResult(*GetHitResult(), true); // 调用AddHitResult函数，true参数表示进行深拷贝
		}
		return NewContext; // 返回新创建的上下文对象
	}

	virtual UScriptStruct* GetScriptStruct() const override // 重写父类的虚函数GetScriptStruct，获取本结构体的UScriptStruct
	{
		return FLyraGameplayEffectContext::StaticStruct(); // 返回FLyraGameplayEffectContext的静态结构体信息
	}

	/** 重写父类函数，用于序列化新增的字段 */
	virtual bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) override; // 成员函数声明，网络序列化函数

	/** 
	 * 从命中结果中获取物理材质
	 * @return 如果存在命中结果且其包含物理材质，则返回该物理材质指针，否则返回nullptr
	 */
	const UPhysicalMaterial* GetPhysicalMaterial() const; // 成员函数声明，获取物理材质

public: // 公有成员访问标识符
	/** 用于识别同一弹壳中发射的多发子弹的ID */
	UPROPERTY() // UPROPERTY宏，声明一个被反射系统识别的属性
	int32 CartridgeID = -1; // 子弹ID，初始化为-1

protected: // 保护成员访问标识符
	/** 能力源对象（应实现ILyraAbilitySourceInterface接口）。当前未复制 */
	UPROPERTY() // UPROPERTY宏，声明一个被反射系统识别的属性
	TWeakObjectPtr<const UObject> AbilitySourceObject; // 指向能力源对象的弱引用指针，用于避免垃圾回收问题
};

template<> // 模板特化开始
struct TStructOpsTypeTraits<FLyraGameplayEffectContext> : public TStructOpsTypeTraitsBase2<FLyraGameplayEffectContext> // 为FLyraGameplayEffectContext特化TStructOpsTypeTraits模板，继承自TStructOpsTypeTraitsBase2
{
	enum // 枚举定义，用于指定结构体操作特性
	{
		WithNetSerializer = true, // 该结构体支持网络序列化
		WithCopy = true // 该结构体支持复制操作
	};
};